# -*- coding: utf-8 -*- 
"""
Created by hcx on 17-6-22 下午2:51.
@author: 胡超翔
"""
from __future__ import absolute_import
from __future__ import unicode_literals

import logging

from ansible.inventory import Inventory

from autodeploy.apps.common.dynamic_inventory import inventory_str
from autodeploy.libs.ansible_overwrit.callback_rewrit import YunweiCallback
from autodeploy.libs.ansible_overwrit.pbex_rewrit import YunweiPlaybookExecutor
from autodeploy.settings import BASE_DIR

logger = logging.getLogger(__name__)
from collections import namedtuple
from ansible.parsing.dataloader import DataLoader
from ansible.vars import VariableManager
from tempfile import NamedTemporaryFile
import os


class AnsibleTask(object):
    """
        src:本地文件的路径
        dest: 被操控的服务器文件路径
        variable:yaml文件的变量,dir形式
    """
    
    def __init__(self, host_list, playbooks, user, password, operation_log,group_name='all', variable=None,port=None):
        self.host_list = host_list
        self.ansible_ssh_user = user
        self.ansible_ssh_pass = password
        self.playbooks = playbooks
        self.port = port
        self.operation_log=operation_log
        Options = namedtuple(
            'Options', [
                'listtags', 'listtasks', 'listhosts', 'syntax', 'connection', 'module_path',
                'forks', 'remote_user', 'private_key_file', 'ssh_common_args', 'ssh_extra_args',
                'sftp_extra_args', 'scp_extra_args', 'become', 'become_method', 'become_user',
                'verbosity', 'check'
            ]
        )
        # extra_vars = dict(src=src,dest=dest)
        # initialize needed objects
        self.variable_manager = VariableManager()
        
        self.options = Options(
            listtags=False, listtasks=False, listhosts=False, syntax=False, connection='smart',
            module_path='~/.virtualenv/autodeploy/lib/python2.7/site-packages/ansible/modules', forks=100,
            remote_user='root', private_key_file=None, ssh_common_args=None, ssh_extra_args=None,
            sftp_extra_args=None, scp_extra_args=None, become=False, become_method=None, become_user='root',
            verbosity=None, check=False
        )
        self.passwords = dict(vault_pass='secret')
        self.loader = DataLoader()
        
        # create inventory and pass to var manager
        self.hostsFile = NamedTemporaryFile(dir=BASE_DIR + '/hosts/', delete=False)
        hosts_name = inventory_str(group_name, self.host_list, user=self.ansible_ssh_user,
                                   password=self.ansible_ssh_pass,pro=self.port)
        self.hostsFile.write(hosts_name)
        self.hostsFile.close()
        self.inventory = Inventory(loader=self.loader, variable_manager=self.variable_manager,
                                   host_list=self.hostsFile.name)
        self.variable_manager.set_inventory(self.inventory)
        # 给脚本传递变量
        if variable:
            self.variable_manager.extra_vars = variable
        self.ansiblePlay()
    
    def ansiblePlay(self):
        # create play with tasks
        # args = "ls /"
        # play_source = dict(
        #     name="Ansible Play",
        #     hosts='all',
        #     gather_facts='no',
        #     tasks=[
        #         dict(action=dict(module='shell', args='ls /'), register='shell_out'),
        #         dict(action=dict(module='shell', args=args), register='shell_result'),
        #         dict(action=dict(module='debug', args=dict(msg='{{shell_out.stdout}}'))),
        #         dict(action=dict(module='debug', args=dict(msg='{{shell_result.stdout}}'))),
        #     ]
        # )
        # result=dirtFile(settings.BASE_DIR+'/task/test.yml')
        # print result
        # play_source = open(settings.BASE_DIR+'task/test.yml','rb')
        # play = Play().load(play_source, variable_manager=self.variable_manager, loader=self.loader)
        self.play2 = YunweiPlaybookExecutor(playbooks=self.playbooks, inventory=self.inventory,
                                            variable_manager=self.variable_manager,
                                            loader=self.loader,
                                            options=self.options,
                                            passwords=self.passwords,
                                            )
        self.results_callback = YunweiCallback(operation_log=self.operation_log)
        self.play2._tqm._stdout_callback = self.results_callback
    # def get_server_message(self,host_list):
    #     play_source = dict(
    #         name="Ansible Play",
    #         hosts='all',
    #         gather_facts='no',
    #         tasks=[
    #             dict(action=dict(module='setup', args='ls /')),
    #         ]
    #     )
    #     # play_source = open(settings.BASE_DIR+'task/test.yml','rb')
    #     play = Play().load(play_source, variable_manager=self.variable_manager, loader=self.loader)
    #     tqm=None
    #     result=None
    #     try:
    #         tqm=TaskQueueManager(
    #             inventory=self.inventory,
    #             variable_manager=self.variable_manager,
    #             loader=self.loader,
    #             options=self.options,
    #             passwords=self.passwords,
    #             stdout_callback=YunweiCallback()
    #         )
    #         result=tqm.run(play)
    #     except Exception as e:
    #         logger.error('运行错误:%s'%e)
    #     finally:
    #         return result
        
    def run(self):
        try:
            result = self.play2.run()
        except Exception as e:
            logger.error(e)
            result=4
        os.remove(self.hostsFile.name)
        # print self.results_callback.result['fact']
        return result, self.results_callback.result
        
        # if self.results_callback.status_no_hosts:
        #     print self.results_callback.status_no_hosts
        #     code = 1002
        #     results = {'playbook': playbooks, 'msg': self.results_callback.status_no_hosts, 'flag': False,
        #                'executed': False}
        
        # results='no host match in '+self.playbook_path
        # return code, results
        # print play.compile()
        # run it
        # tqm = None
        # try:
        #     tqm = TaskQueueManager(
        #         inventory=self.inventory,
        #         variable_manager=self.variable_manager,
        #         loader=self.loader,
        #         options=self.options,
        #         passwords=self.passwords,
        #         stdout_callback='default',
        #     )
        #     result = tqm.run(play)
        # finally:
        #     if tqm is not None:
        #         tqm.cleanup()
        #     # os.remove(self.hostsFile.name)
        #     self.inventory.clear_pattern_cache()
        #     print result
        #     return result
        
        # def get_result(self):
        #     self.result_all = {'success': {}, 'fail': {}, 'unreachable': {}}
        #     return self.results_callback.results
        # for host, result in self.results_callback.host_ok.items():
        #     self.result_all['success'][host] = result._result
        #
        # for host, result in self.results_callback.host_failed.items():
        #     self.result_all['failed'][host] = result._result['msg']
        #
        # for host, result in self.results_callback.host_unreachable.items():
        #     self.result_all['unreachable'][host] = result._result['msg']
        #
        # for i in self.result_all['success'].keys():
        #     print i, self.result_all['success'][i]
        #
        # print self.result_all
        # print self.result_all['fail']
        # print self.result_all['unreachable']


